package com.paradogs.demo.logic.manager.base;

import com.baomidou.mybatisplus.extension.service.IService;
import com.paradogs.framework.common.entity.base.BaseEntity;
import com.paradogs.framework.core.queue.DBUpdatMsg;
import com.paradogs.framework.core.queue.PRQueueHolder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @author: yumi
 * @date: 2023/11/23  14:01
 * @Description: TODO
 */
@Slf4j
public abstract class BaseManager<E extends BaseEntity, D extends IService<E>> {

    @Autowired
    private D dao;

    @Setter
    private E data;

    /**
     * 数据是否被修改并且未同步到客户端
     */
    @Getter
    @Setter
    private boolean dirty;

    /**
     * 获取数据，克隆一份
     * @return
     */
    public E getData() {
        E e = null;
        try {
            e = dao.getEntityClass().newInstance();
        } catch (InstantiationException instantiationException) {
            instantiationException.printStackTrace();
        } catch (IllegalAccessException illegalAccessException) {
            illegalAccessException.printStackTrace();
        }
        BeanUtils.copyProperties(data, e);
        return e;
    }

    /**
     * 加载玩家数据
     * @param uid
     */
    public void loadData(Long uid) {
        this.data = dao.getById(uid);
        this.dirty = true;
        if (this.data == null) {
            try {
                this.data = dao.getEntityClass().newInstance();
                this.data.setUid(uid);
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        log.debug("Load {}: {}", this.getClass().getSimpleName(), this.data);
    }

    /**
     * 更新数据，待优化：数据值真实变化时再改变状态位 | 深克隆
     * @param data
     */
    public void updateData(E data) {
//        if (!this.data.equals(data)) {
//
//        }
        this.data = data;
        this.dirty = true;
        // 更新数据加入到 DB 队列
        PRQueueHolder.putMsg(PRQueueHolder.QueueType.DB, new DBUpdatMsg(data.getUid(), dao, data));
    }
    public void setData(E data) {
        updateData(data);
    }

    /**
     * 循环检测
     */
    void heartBeat() {}

}
